﻿using AutoMapper;
using MiniErp.Common.Cache;
using MiniErp.Common.DB.MySqlDB;
using MiniErp.Entity.DataStreams.BOs;
using MiniErp.Entity.DataStreams.DOs;
using MiniErp.Entity.DataStreams.DOs.Notice;
using MiniErp.Entity.DataStreams.DTOs.Notice;
using MiniErp.Repository.BaseRepository;
using MiniErp.Repository.UnitOfWorkCore;
using MiniErp.Service.JWTService.IService;
using MiniErp.Service.BusinessService.IService.Notice;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MiniErp.Service.BusinessService.Service.Notice
{
    /// <summary>
    /// 公告服务
    /// </summary>
    public class NoticeService : BaseService, INoticeService
    {
        /// <summary>
        /// 公告仓储
        /// </summary>
        private readonly BaseRepository<MysqlContext, Notices> _nr;
        /// <summary>
        /// 岗位公告仓储
        /// </summary>
        private readonly BaseRepository<MysqlContext, JobsNotices> _jnr;
        /// <summary>
        /// 岗位仓储
        /// </summary>
        private readonly BaseRepository<MysqlContext, Jobs> _jr;
        /// <summary>
        /// 用户回复公告服务
        /// </summary>
        private readonly IUserInfoNoticesReplyService _uinrService;
        private readonly ICache _cache;
        private readonly ITokenService _tokenService;
        public NoticeService(IMysqlUnitOfWork mysqlUnitOfWork, IMapper mapper, ICache cache, ITokenService tokenService, IUserInfoNoticesReplyService uinrService)
            : base(mysqlUnitOfWork, mapper)
        {
            _nr = mysqlUnitOfWork.CreateRepository<MysqlContext, Notices>();
            _jnr = mysqlUnitOfWork.CreateRepository<MysqlContext, JobsNotices>();
            _jr = mysqlUnitOfWork.CreateRepository<MysqlContext, Jobs>();
            _cache = cache;
            _tokenService = tokenService;
            _uinrService = uinrService;
        }
        public class test1
        {
            public List<UserInfo> users;
        }


        public async Task<bool> AddNoticesAsync(AddNoticesDTO noticesDTO)
        {
            var notices = _mapper.Map<Notices>(noticesDTO);
            notices.UpdateTime = notices.CreateTime = DateTime.Now;
            //新增公告到公告表
            _nr.AddInfo(notices);
            var result = await _mysqlUnitOfWork.SaveAsync();//执行事务
            if (result == 0) throw new ExceptionBO("新增公告失败");
            //记录数据库操作次数
            var resultnums = 0;
            //存储所有用户回复数据
            var addUserInfoNoticesReplyDTOs = new List<AddUserInfoNoticesReplyDTO>();
            noticesDTO.JobsId.ForEach(async jobsId =>
            {
                //新增公告到岗位公告表=>哪些岗位可以看到此公告
                _jnr.AddInfo(new JobsNotices { NoticesId = notices.NoticesId, JobsId = jobsId });
                //新增公告信息到用户回复集合
                if (notices.IsReply)
                {
                    //查询到指定岗位id的岗位信息
                    var jobs = await _jr.GetInfoAsync(item => item.JobsId == jobsId);
                    //取岗位下所有用户信息
                    jobs.UserInfos.ForEach(item =>
                    {
                        addUserInfoNoticesReplyDTOs.Add(new AddUserInfoNoticesReplyDTO
                        {
                            userInfoId = item.UId,
                            Reply = null,
                            NoticeId = notices.NoticesId
                        });
                    });
                }
            });
            resultnums += noticesDTO.JobsId.Count;
            resultnums += _uinrService.AddUserInfoNoticesReplys(addUserInfoNoticesReplyDTOs);
            result = await _mysqlUnitOfWork.SaveAsync();//执行事务
            return result == resultnums   //不等于数据库操作次数则出现异常
                ? true
                : await _mysqlUnitOfWork.DataRollback("增加失败", 2);
        }



        public async Task<bool> DeleteNoticesAsync(int noticesId)
        {
            var notices = await _nr.GetReadOnlyInfoAsync(item => item.NoticesId == noticesId);
            if (notices == null) throw new ExceptionBO("该公告信息不存在");
            //当前非公告编写人修改公告时
            if (_tokenService.GetUId() != notices.UserInfoId) throw new ExceptionBO("警告，不要非法操作数据", 400);
            _nr.DeleteInfo(notices);
            //记录数据库操作次数
            var resultnums = 1;
            var jonbsNotices = await _jnr.GetReadOnlyInfoAsyncs(item => item.NoticesId == noticesId);
            _jnr.DeleteInfo(jonbsNotices);
            resultnums += jonbsNotices.Count;
            var UserNoticeIds = await _uinrService.GetUserInfoNoticesReplyByNoticesIdAsync(noticesId);
            resultnums += _uinrService.DeleteUserInfoNoticesReplys(UserNoticeIds);
            var result = await _mysqlUnitOfWork.SaveAsync();
            return result == resultnums
                ? true
                : await _mysqlUnitOfWork.DataRollback("删除此公告失败");
        }

        public async Task<List<NoticesDTO>> GetAllNoticesAsync(int page, int num)
        {
            var notices = await _nr.GetReadOnlyInfoAsyncs<int>(page, num, "NoticesId");
            return notices.Count == 0
                ? null
                : _mapper.Map<List<NoticesDTO>>(notices);
        }

        public async Task<List<NoticesDTO>> GetAllNoticesByTimeAsync(DateTime starttime, DateTime endtime, int page, int num)
        {
            var notices = await _nr.GetReadOnlyInfoAsyncs<int>(page, num, "NoticesId", item => item.UpdateTime >= starttime && item.UpdateTime <= endtime);
            return notices.Count == 0
                ? null
                : _mapper.Map<List<NoticesDTO>>(notices);
        }

        public async Task<List<NoticesDTO>> GetNoticesBySystemsIdAsync(int uid, int page, int num)
        {
            var notices = await _nr.GetReadOnlyInfoAsyncs<int>(page, num, "NoticesId", item => item.UserInfoId == uid);
            return notices.Count == 0
                ? null
                : _mapper.Map<List<NoticesDTO>>(notices);
        }

        public async Task<bool> UpdateNoticesAsync(UpdateNoticesDTO noticesDTO)
        {
            var oldnotices = await _nr.GetInfoAsync(item => item.NoticesId == noticesDTO.NoticesId);
            if (oldnotices == null) throw new ExceptionBO("要修改的公告不存在");
            //获取可看到此公告的岗位编号集合
            var jobsidlist = oldnotices.JobsNotices.Select(item => item.JobsId).ToList();
            //结束当前实体跟踪
            _mysqlUnitOfWork.EndTracking<Notices>();
            var notices = _mapper.Map<Notices>(noticesDTO);
            notices.CreateTime = oldnotices.CreateTime;
            notices.UpdateTime = DateTime.Now;
            notices.UserInfoId = oldnotices.UserInfoId;
            //当前非公告编写人修改公告时
            if (_tokenService.GetUId() != oldnotices.UserInfoId) throw new ExceptionBO("警告，不要非法操作数据", 400);
            _nr.UpdateInfo(notices);
            var result = await _mysqlUnitOfWork.SaveAsync();
            if (result == 0) throw new ExceptionBO("修改公告失败");
            //*
            //修改成功后根据修改参数作出响应处理(岗位公告表以及回复表)
            //*
            //记录数据库操作次数
            var resultnums = 0;

            if (oldnotices.IsReply == false && notices.IsReply == true)//当不需要回复改为需要回复时
            {
                //存储所有用户回复数据
                var addUserInfoNoticesReplyDTOs = new List<AddUserInfoNoticesReplyDTO>();
                noticesDTO.JobsId.ForEach(async jobsId =>
                {
                    //新增公告信息到用户回复集合
                    //查询到指定岗位id的岗位信息
                    var jobs = await _jr.GetInfoAsync(item => item.JobsId == jobsId);
                    //取岗位下所有用户信息
                    jobs.UserInfos.ForEach(item =>
                    {
                        addUserInfoNoticesReplyDTOs.Add(new AddUserInfoNoticesReplyDTO
                        {
                            userInfoId = item.UId,
                            Reply = null,
                            NoticeId = notices.NoticesId
                        });
                    });
                    resultnums += _uinrService.AddUserInfoNoticesReplys(addUserInfoNoticesReplyDTOs);

                });
            }

            else if (oldnotices.IsReply == true && notices.IsReply == false)//当需要回复改为不需要回复时
            {
                //从公告回复表中删除此公告相关
                var usernotices = await _uinrService.GetUserInfoNoticesReplyByNoticesIdAsync(notices.NoticesId);
                resultnums += _uinrService.DeleteUserInfoNoticesReplys(usernotices);
            }

            else if (oldnotices.IsReply && notices.IsReply == true)    //回复状态为需要回复并且未发生改变时
            {
                if (noticesDTO.JobsId != jobsidlist)//可查看此公告岗位发生变更时
                {
                    //存储所有用户回复数据
                    var addUserInfoNoticesReplyDTOs = new List<AddUserInfoNoticesReplyDTO>();
                    //获取新增岗位
                    var addjobs = noticesDTO.JobsId.Where(item => jobsidlist.Contains(item) == false).ToList();
                    addjobs.ForEach(async jobsId =>
                    {
                        //新增公告到岗位公告表=>哪些岗位可以看到此公告
                        _jnr.AddInfo(new JobsNotices { NoticesId = notices.NoticesId, JobsId = jobsId });
                        resultnums++;
                        //查询到指定岗位id的岗位信息
                        var jobs = await _jr.GetInfoAsync(item => item.JobsId == jobsId);
                        //取岗位下所有用户信息
                        jobs.UserInfos.ForEach(item =>
                        {
                            addUserInfoNoticesReplyDTOs.Add(new AddUserInfoNoticesReplyDTO
                            {
                                userInfoId = item.UId,
                                Reply = null,
                                NoticeId = notices.NoticesId
                            });
                        });
                        resultnums += _uinrService.AddUserInfoNoticesReplys(addUserInfoNoticesReplyDTOs);
                    });
                    //获取删除岗位
                    var deletejobs = jobsidlist.Where(item => noticesDTO.JobsId.Contains(item) == false).ToList();
                    deletejobs.ForEach(async jobsid =>
                    {
                        //删除岗位信息表数据
                        var jonbsNotices = await _jnr.GetReadOnlyInfoAsyncs(item => item.NoticesId == notices.NoticesId && item.JobsId == jobsid);
                        _jnr.DeleteInfo(jonbsNotices);
                        resultnums += jonbsNotices.Count;
                        //删除回复表数据
                        var UserNoticeIds = await _uinrService.GetUserInfoNoticesReplyByNoticesIdAndJobsIdAsync(notices.NoticesId, jobsid);
                        resultnums += _uinrService.DeleteUserInfoNoticesReplys(UserNoticeIds);
                    });
                }
            }
            result = await _mysqlUnitOfWork.SaveAsync();
            return result == resultnums
                ? true
                : await _mysqlUnitOfWork.DataRollback("修改失败,数据出现异常");//等于其他值说明出现了异常状况，回滚事务

        }


    }
}
